\documentclass{article}

\usepackage[top=2.5cm, bottom=2.5cm, left=2cm, right=2cm]{geometry}
\usepackage{fancyhdr}
\lhead{\bsc{Programmation Orientee Objet}}
\rhead{\bsc{TD4}}
\renewcommand{\headrulewidth}{1px}
\lfoot{ \bsc{Enseirb-Matmeca}}
\rfoot{ \bsc{Informatique - I2}}
\renewcommand{\footrulewidth}{1px}
\pagestyle{fancy}
\usepackage{wrapfig}
\usepackage{multicol}
\usepackage{textcomp}
\usepackage[T1]{fontenc}
\usepackage{setspace}
\usepackage{graphicx} 

%\usepackage[vlined,lined,boxed,french,longend]{algorithm2e}

\usepackage{graphicx}
\usepackage[french]{babel}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{mathrsfs}
\usepackage{xcolor}
\usepackage[utf8]{inputenc}
%%%%%%%%%%%%%%%% Variables %%%%%%%%%%%%%%%%
%\def\projet{2}
\def\titre{Lot 2: Des nouveaux caractères d'usagers \\
  --------------------- \\Héritage et factorisation}
%\def\groupe{2}
\def\equipe{piyovimoad}
\def\responsible{ydubernet}
\def\tandemi{avilliermet, vpomier}
\def\tandemii{mmegzari, ppocquetduhautjusse}

\begin{document}
%%%%%%%%%%%%%%%% Header %%%%%%%%%%%%%%%%
\noindent\begin{minipage}{\textwidth}
\vskip 0mm
\noindent
    { \begin{tabular}{p{7.5cm}}
        {\bfseries \sffamily
          Rapport du TD n°5 de l'équipe \equipe}
        \begin{center}{\itshape \titre}\end{center}
    \end{tabular}}
    \hfill 
    \fbox{\begin{tabular}{l}
        {~\hfill \bfseries \sffamily 22/10/12 \hspace{1.5mm} \hfill~} \\[2mm] 
        Coordinateur : \responsible \\
        Tandem1 : \tandemi \\
        Tandem2 : \tandemii
    \end{tabular}}
    \vskip 4mm ~

    \parbox{\textwidth}{\small \textit{Travail restant à la fin de la séance~:}

Le cas particulier de cette séance a impliqué que sur les deux tandems, un terminait le code de la séance précédente tandis que l'autre avançait le code de ce td.\\
A l'issue de la séance, il restait dans la partie 3 l'implémentation de \texttt{PassagerStresse} ainsi que tous les tests et la partie 4.
}

    \vskip 1mm ~
\end{minipage}




%%%%%%%%%%%%%%%% Main part %%%%%%%%%%%%%%%%
\section{Introduction}
L'objectif de ce TD était de construire une architecture de classes permettant d'ajouter au package de nouvelles classes \texttt{Passager}/\texttt{Usager} tout en \emph{évitant la duplication de code} ainsi qu'en ajoutant des caractères de passager \emph{sans modifier le code déjà existant}.

\section{Pourquoi l'héritage}
\subsection{Solution avec une seule classe}
Dans le cas de la première solution avec une seule classe, le principal problème est que cela implique une modification conséquente du code existant. Principalement dans les méthodes de \emph{PassagerStandard} ainsi que dans les méthodes faisant appels à celles-ci.

\subsection{Solution avec une relation de type/sous-type}
Il est important de conserver la relation de \emph{type/sous-type} pour cacher le code du programme au client (avec les problèmes de portée sous-jacents).
De plus, cela permet de garder les différentes classes de passagers indépendantes les unes des autres.

Notre problème ici est donc la duplication de code. En effet, pour conserver la relation \emph{type/sous-type}, il faudra copier le code de \emph{PassagerStandard} dans chaque nouvelle classe.

L'utilisation d'un lien \emph{a-un} se ferait en ayant une classe séparée qui contiendrait les méthodes communes à toutes les classes.

\subsection{Solution avec l'héritage de classe}

L'héritage de classe permet à une classe dite fille d'hériter des attributs et méthodes d'une autre classe dite mère. Ainsi, dans notre nouvelle implémentation, la classe \texttt{PassagerStandard} ne sera plus une classe de base. A la place, on définit une nouvelle classe \texttt{PassagerAbstrait}.

Dans le cas de l'héritage de classe, le remaniement du code n'impliquera pas de moficiation de l'existant mais seulement l'ajout de nouvelles méthodes. En l'occurence, les méthodes spécifiques à chaque type de passager. Les modifications conséquentes sont uniquement le déplacement des méthodes communes à tous les types de passagers dans la \emph{classe abstraite} \texttt{PassagerAbstrait}, tandis que \texttt{PassagerStandard} ne conservera que les méthodes qui lui sont propres.
\\

Le nouveau diagramme de classe est en figure 1.

%Diagramme de classe.

\begin{figure}[h!]
\begin{center}

\includegraphics[scale=0.60]{diagramme_classe_passager.png}
\caption{Diagramme de classe passager pour l'héritage}
\end{center}
\end{figure}

\section{L'héritage de classe}

\subsection{La classe PassagerAbstrait}
Cette classe est déclarée abstraite car elle ne doit pas être instanciable,  elle sert de classe de base pour les classes \texttt{PassagerStandard}, \texttt{PassagerLunatique} et \texttt{PassagerStressé} qui en hériteront.
\\

De plus, il est nécessaire que cette classe possède un constructeur afin de permettre l'initialisation des attributs qui ne sont accessibles que dans cette classe et ainsi permettre l'instanciation des classes qui en héritent.

\subsection{La classe PassagerStandard}
Si la variable \texttt{destination} de \texttt{PassagerAbstrait} était précédée par le mot-clé \texttt{protected}, cela ne respecterait pas l'encapsulation car les classes qui en héritent pourraient y accéder et les modifier, ce qui génére une dépendence de réalisation. Il nous faut donc masquer cette variable.

De manière à retirer le mot clé \texttt{protected} de la variable stockant la destination, on construit une méthode qui permet de retourner la destination dans la classe abstraite \texttt{PassagerAbstrait} et la déclare en \texttt{protected} pour qu'elle soit accessible dans les classes filles : \\

\begin{verbatim}
      protected final int reDestination(){
         return destination;
      }
\end{verbatim}
\\

L'appel au constructeur de la classe de base est nécessaire vu que les constructeurs ne sont pas hérités et l'initialisation de l'état définit dans la classe de base est non accessible et nécessaire. Donc on définit les constructeurs des sous-classes comme suit :

\begin{verbatim}
    public PassagerStandard(String nom, int destination){
       super(nom,destination);
    }
\end{verbatim}

Si le corps du constructeur de \texttt{PassagerStandard} est vide, on obtient le message d'erreur \texttt{cannot find symbol} car lorsqu'il n'y a pas d'instruction de type \texttt{super()} ou \texttt{this()} sur la première ligne de code du constructeur, le compilateur fait appel au constructeur \emph{sans paramètre} de la classe de base (ici, \texttt{PassagerAbstrait}). Sauf qu'il n'y a aucun constructeur de \texttt{PassagerAbstrait} sans paramètre. Donc le compilateur ne trouve pas le constructeur et il y a une erreur.

\section{Définir ce qu'il faut paramétrer}

Une fois les méthodes \texttt{monterDans} et \texttt{nouvelArret} écrites dans les deux classes \texttt{PassagerStresse} et \\\texttt{PassagerLunatique}, on remarque que le  code dupliqué au niveau de la méthode \texttt{monterDans} est la ligne : \\
\begin{verbatim}
       Bus b = (Bus) t;

\end{verbatim}
Alors que le code dupliqué au niveau de \texttt{nouvelArret} est toute la partie concernant la sortie du bus, à savoir : \\
\begin{verbatim}
       if(reDestination() <= numeroArret)
           bus.demanderSortie(this);
\end{verbatim} 

Ainsi, le code dupliqué est factorisé dans la classe de base \texttt{PassagerAbstrait} en y déplaçant les deux méthodes \texttt{monterDans} et \texttt{nouvelArret}, puis en créant deux nouvelles méthodes \texttt{choixMonterDans} et \texttt{choixChangerPlace} qui contiennent le code variable et qui seront redéfinies par les classes dérivées.

L'appel à la méthode de base (ex : \texttt{monterDans}) va appeler la bonne méthode redéninie dans la bonne classe dérivée car dans le mécanisme du \emph{polymorphisme}, la liaison dynamique est employée sur les méthodes d'instance. Ainsi, la liaison entre l'envoi du message et l'adresse de la méthode à exécuter s'effectue à l'exécution, en fonction du type de l'instance manipulée.


\subsection{La classe PassagerAbstrait}

On déclare les deux méthodes \texttt{choixChangerPlace()} et \texttt{choixPlaceMontee()} abstraites car ainsi on est sûr que les classes filles devront redéfinir et respecter le même prototype défini dans cette classe abstraite.

Ces deux méthodes sont déclarées \texttt{protected} car elles ne doivent être accessibles que par les classes héritées.

On déclare les autres méthodes de la classe comme finales vu qu'elles sont communes à tous les caractères des passagers et ainsi on est assuré que ces méthodes ne pourront pas être définies dans une sous-classe.

\subsection{Les autres classes de caractères}
On déclare les classes \texttt{PassagerStandard}, \texttt{PassagerStresse}, \texttt{PassagerLunatique} comme finales de manière à ce qu'elles ne puissent pas être héritées vu qu'elles définissent des caractères spécifiques dont le comportement est bien défini.


\section{Factoriser les tests}
La majorité des tests effectués sont communs à tous les caractères de passagers, ainsi il est impératif de factoriser les classes de test en créant une classe abstraite de tests pour éviter une grande duplication du code et pour respecter la hiérarchie de classe définie. 


\subsection{Construction d'une classe abstraite}
Une fois la classe \texttt{TestPassagerAbstrait} créée et les classes \texttt{TestPassagerStandard}, \texttt{TestPassagerStresse} et \texttt{TestPassagerLunatique} héritées de celle-ci, nous avons au total 43 tests exécutés. Avant toute opération, il y en avait 26.

Ceci s'explique par le fait que l'on a rajouté deux tests supplémentaires par nouvelle classe pour \\\texttt{TestPassagerLunatique} et \texttt{TestPassagerStresse}, mais aussi car les tests de \texttt{TestPassagerAbstrait} (anciennement dans \texttt{TestPassagerStandard}) sont effectuées dans chaque classe de test. Ils sont donc exécutés en triple, mais c'est une preuve d'indépendence entre les classes \texttt{TestPassagerStandard}, \texttt{TextPassagerStresse} et \texttt{TestPassagerLunatique} puisque chacune va tester que tous les tests fonctionnent. On peut donc lancer des tests sur une seule classe à la fois, tout en étant sûr que tous les tests unitaires nécessaires à celle-ci passeront.

Ainsi, pour lancer tous les tests spécifiques à une classe caractère, il faut définir une méthode \texttt{lancer} qui fait appel à la méthode \texttt{lancer}
définie dans la classe de base \texttt{PassagerAbstrait}, via le mécanisme \texttt{super} : \texttt{super.lancer()} , pour ainsi lancer tous les tests communs aux trois classes. Et enfin faire appel aux tests des deux méthodes \texttt{choixChangerPlace} et \texttt{choixMonterDans}.

Reste à régler un problème d'instanciation, vu que les tests contenus dans \texttt{PassagerAbstrait} sont toujours lancés sur des instances de \texttt{PassagerStandard}.  


\subsection{Paramétrer l'instanciation}
Pour paramétrer l'instanciation, on construit une méthode abstraite dans la classe \texttt{TestPassagerAbstrait} qui sera redéfinie dans les classes filles et qui servira à renvoyer la bonne instance de \texttt{PassagerAbstrait} à tester. 

Donc lors de l'exécution des tests et suite à l'appel de la méthode \texttt{lancer()} de la classe de base, l'appel à la bonne méthode \texttt{creerPassager} est déclenché grâce à la liaison dynamique. Ainsi, les tests factorisés sont lancés sur le bon type d'instance.
 
Lorsque l'on définit \texttt{creerPassager}, on prend comme type de retour \texttt{PassagerAbstrait} vu que les méthodes à tester ne sont pas toutes définies dans l'interface \texttt{Usager}, donc quelques envois de messages ne sont pas autorisés.


\section{Conclusion}
La progresssion dans ce TD a été limitée par le fait qu'il s'est déroulé seulement 3 jours après le précédent et nous n'avions donc pas encore terminé le précédent.
\\

Ce TD nous a permit de mettre en pratique l'héritage et la factorisation, et particulièrement de peser toute la puissance de ces mécanismes limitant la perte de temps dans le recodage de ce qui existe déjà et dans la modification d'un existant opérationnel lorsque l'on souhaite créer de nouvelles classes pouvant être héritées d'une classe déjà existante.


\end{document}
